/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_ui.htm
 *
 * Zhiqim UI is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
 
+(function(Z) 
{//BEGIN

/********************************************/
//可编辑类定义
/********************************************/
Z.Editable = Z.Class.newInstance();
Z.Editable.v = "8.0.4";
Z.Editable.cache = new Z.HashMap();
Z.Editable.get = function(elem)
{
    if (Z.T.isString(elem))
        elem = Z.D.id(elem);
    return Z.Editable.cache.get(elem);
};

/********************************************/
//编辑类属性和方法
/********************************************/
Z.Editable.prototype = 
{
    defaults :
    {//缺省值
        elem:null
    },
    
    init: function()
    {//初始化
        if (!this.elem)
            return;
            
        this.$elem = Z(this.elem);
        
        //获取配置的内容参数，包括文本和回调函数，及相关的配置项
        this.value = this.$elem.attr("data-value") || "";
        this.callback = this.$elem.attr("data-save") || null;
                
        var valueClass = this.$elem.attr("data-value-class") || null;
        var valueStyle = this.$elem.attr("data-value-style") || null;
        var inputClass = this.$elem.attr("data-input-class") || null;
        var inputStyle = this.$elem.attr("data-input-style") || null;
        var inputMaxLength = this.$elem.attr("data-input-maxlength") || null;
        var inputCheck = this.$elem.attr("data-input-check") || null;
        var buttonClass = this.$elem.attr("data-button-class") || null;
        var buttonStyle = this.$elem.attr("data-button-style") || null;
        
        //第一步，创建Editable
        this.$show = Z('<span class="z-show"><span></span><i class="z-ico z-pen"></i></span>');
        this.$edit = Z('<span class="z-edit"><input class="z-input z-small" value="">&nbsp;<div class="z-button">保存</div></span>');
        this.$elem.addClass("z-editable").append(this.$show).append(this.$edit);
        
        this.$value = this.$show.find("span").html(this.value);
        this.$pen = this.$show.find("i");
        this.$input = this.$edit.find("input").val(this.value);
        this.$button = this.$edit.find("div");
        
        if (inputMaxLength){
            this.$input.attr("maxlength", inputMaxLength);
        }
        
        if (inputCheck && Z.Input)
        {//增加输入验证
            var options = Z.AR.toObject(inputCheck, ";");
            this.check = new Z.Input({elem: this.$input[0], options: options});
        }
                
        //第二步，设置Editable可由配置项配置的样式，和回调函数名称转为函数对象
        if (valueClass)
            this.$value.addClass(valueClass);
            
        if (valueStyle)
            this.$value.style(valueStyle);
            
        if (inputClass)
            this.$input.addClass(inputClass);
            
        if (inputStyle)
            this.$input.style(inputStyle);
            
        if (buttonClass)
            this.$button.addClass(buttonClass);
        else
            this.$button.addClass("z-small");
            
        if (buttonStyle)
            this.$button.style(buttonStyle);
            
        if (this.callback)
            this.callback = Z.evals(this.callback);

        //第三步，注册点击事件，全文档点击时show，除pen和button两种情况表示编辑和保存，另外在编辑状态下阻止冒泡点击事件到全文档。
        Z(document).click(this.show, this);
        this.$pen.click(this.edit, this);
        this.$edit.click(function(e){Z.E.stop(e);});
        this.$button.click(this.save, this);
    },
    val: function(value)
    {
        this.value = value;
        this.show();
    },
    show: function()
    {
        this.$value.html(this.value);
        this.$value.show();
        this.$pen.inBlock();
        
        //编辑状态置为显示状态的值
        this.$input.val(this.value);
        this.$edit.hide();
    },
    edit: function(e)
    {
        Z.E.stop(e);
        
        this.$edit.inBlock();
        this.$value.hide();
        this.$pen.hide();
    },
    save: function(e)
    {
        Z.E.stop(e);
        
        var value = this.$input.val();
        if (value == this.value)
        {//未修改值
            this.show();
            return;
        }
        
        if (!Z.T.isFunction(this.callback))
        {//没有配置回调函数不处理保存事件
            Z.alert("请先配置[data-save]函数名");
            return;
        }
          
        var ret = this.callback.call(this.elem, value);
        if (ret === false)
        {//回调函数返回fase不修改值，由调用方处理错误
        }
        else if (Z.T.isString(ret))
        {//回调函数返回错误信息，在可编辑框中提示错误
            Z.alert(ret);
        }
        else
        {//未返回或返回true保存并显示
            this.value = value;
            this.show();
        }
    }
};

/********************************************/
//刷新静态函数和第一次加载
/********************************************/

Z.Editable.load = function()
{
    var elements = Z.D.attrs("data-role", "z-editable");
    if (!elements || elements.length == 0)
        return;

    for(var i=0;i<elements.length;i++)
    {
        if (!Z.EL.has(elements[i], "data-value"))
            continue;
        
        var editable = new Z.Editable({elem: elements[i]});
        Z.Editable.cache.put(elements[i], editable);
    }
};

Z.onload(Z.Editable.load);

//END
})(zhiqim);